﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StockAna
{
    public class StockSafe
    {
        private string id;
        public string code { get; set; }
        private string _name;
        public string name
        {
            get
            {
                if (string.IsNullOrEmpty(_name))
                {
                    return StockPrize.Find(code).name;
                }
                return _name;
            }
            set
            {
                _name = value;
            }
        }
        public double profit0 { get; set; }
        public double profit_rate { get; set; }
        public double float_asset { get; set; }
        public double float_debt { get; set; }
        public double depreciation { get; set; }
        public double pay { get; set; }
        public double capital { get; set; }
        public double bonus { get; set; }
        public double refix { get; set; }
        public string note { get; set; }

        public double profit1
        {
            get { return profit0 * profit_rate; }
        }
        public double profit2
        {
            get { return profit1 * profit_rate; }
        }
        public double running0
        {
            get { return Math.Max(float_asset - float_debt, 0); }
        }
        public double running1_inc
        {
            get { return Math.Max(running0 * profit_rate - running0, 0); }
        }
        public double running2
        {
            get { return running0 * profit_rate * profit_rate; }
        }
        public double running2_inc
        {
            get { return Math.Max(running2 - running0 * profit_rate, 0); }
        }
        public double depreciation1
        {
            get { return depreciation * profit_rate; }
        }
        public double depreciation2
        {
            get { return depreciation1 * profit_rate; }
        }
        public double pay1
        {
            get { return pay * profit_rate; }
        }
        public double pay2
        {
            get { return pay1 * profit_rate; }
        }
        public double bonus2
        {
            get
            {
                return 2 * bonus * capital;
            }
        }
        public double discount
        {
            get
            {
                Rate rate = new Rate();
                double d1 = (profit1 + depreciation1 - running1_inc - pay1) * rate.Discount(1);
                double d2 = (profit2 + depreciation2 - running2_inc - pay2) * rate.Discount(2);
                return d1 + d2 + running2 * rate.Discount(2) + refix + bonus2 * rate.Discount(2);
            }
        }
        public double safe_rate
        {
            get
            {
                StockPrize prize = StockPrize.Find(code);
                if (prize.prize > 0.01)
                {
                    return discount / (prize.prize * capital);
                }
                else
                {
                    return -10;
                }
                
            }
        }

        public static StockSafe Find(string code)
        {
            SQLiteDataReader reader = Config.ReadSql(string.Format("SELECT * FROM stock_safes WHERE code='{0}' LIMIT 1;", code));
            if (reader.Read())
            {
                return Create(reader);
            }

            return new StockSafe(code);
        }

        public static StockSafe Create(SQLiteDataReader reader)
        {
            StockSafe ss = new StockSafe("");
            ss.id = reader.GetString(0);
            ss.code = ss.id;
            ss.profit0 = reader.GetDouble(1);
            ss.profit_rate = reader.GetDouble(2);
            ss.float_asset = reader.GetDouble(3);
            ss.float_debt = reader.GetDouble(4);
            ss.depreciation = reader.GetDouble(5);
            ss.pay = reader.GetDouble(6);
            ss.capital = reader.GetDouble(7);
            ss.bonus = reader.GetDouble(8);
            ss.refix = reader.GetDouble(9);
            ss.name = reader.GetString(11);
            ss.note = reader.GetString(12);

            return ss;
        }

        //all
        public static StockSafe[] All()
        {
            ArrayList arr = new ArrayList();
            SQLiteDataReader reader = Config.ReadSql("SELECT * FROM stock_safes;");
            while (reader.Read())
            {
                StockSafe ss = Create(reader);
                arr.Add(ss);
            }

            return arr.ToArray(typeof(StockSafe)) as StockSafe[];
        }
        
        public static StockSafe[] Top(int max)
        {
            ArrayList arr = new ArrayList();
            SQLiteDataReader reader = Config.ReadSql(string.Format("SELECT * FROM stock_safes ORDER BY safe_rate DESC LIMIT {0};", max));
            while (reader.Read())
            {
                StockSafe ss = Create(reader);
                arr.Add(ss);
            }

            return arr.ToArray(typeof(StockSafe)) as StockSafe[];
        }

        StockSafe(string c)
        {
            code = c;
        }

        //save
        public void Save()
        {
            if (string.IsNullOrEmpty(id))
            {
                id = code;
                string sql = string.Format("INSERT INTO stock_safes VALUES('{0}',{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},'{11}','{12}');",
                    id, profit0, profit_rate, float_asset, float_debt, depreciation, pay, capital, bonus, refix, safe_rate, name, note);
                Config.RunSql(sql);
            }
            else
            {
                string sql = string.Format(@"UPDATE stock_safes SET profit0={0}, profit_rate={1}, float_asset={2}, float_debt={3}, depreciation={4}, pay={5}, capital={6}, bonus={7}, refix={8}, safe_rate={9}, note='{10}', name='{11}' where code='{12}';",
                    profit0, profit_rate, float_asset, float_debt, depreciation, pay, capital, bonus, refix, safe_rate, note, name, id);
                Config.RunSql(sql);
            }
        }
    }
}
